#pragma once
#include <iostream>
#include <cmath>

using namespace std;

template<class T>
class Interval
{
public:
	Interval(){ upper = lower = 0; }
	Interval(T mean, double procent)
	{
		lower = mean - mean * procent / 100;
		upper = mean + mean * procent / 100;
		cout << lower << ":" << upper << endl;
	}
	~Interval(){}
	T mean()
	{
		return (lower + upper) / 2;
	}
	double relative_error()
	{
		return (upper + lower) / mean();
	}
	double absolut_fel()
	{
		return fmax(abs(upper - mean()), abs(lower - mean()));
	}
	double procentuellt_fel()
	{
		return absolut_fel() / mean() * 100;
	}
	friend Interval<T> operator+(Interval<T> &lop, Interval<T> &rop)
	{
		Interval<T> m;
		m.upper = lop.upper + rop.upper;
		m.lower = lop.lower + rop.lower;
		return m;
	}
	friend Interval<T> operator-(Interval<T> &lop, Interval<T> &rop)
	{
		Interval<T> m;
		m.lower = lop.lower - rop.upper;
		m.upper = lop.upper - rop.lower;
		return  m;
	}
	friend Interval<T> operator*(Interval<T> &lop, Interval<T> &rop)
	{
		Interval<T> m;
		m.lower = fmin(fmin(lop.lower*rop.lower, lop.lower*rop.upper),
			fmin(lop.upper*rop.lower, lop.upper*rop.upper));
		m.upper = fmax(fmax(lop.lower*rop.lower, lop.lower*rop.upper),
			fmax(lop.upper*rop.lower, lop.upper*rop.upper));
		return m;
	}
	friend Interval<T> operator/(Interval<T> &lop, Interval<T> &rop)
	{
		Interval<T> m;
		m.lower = fmin(fmin(lop.lower*1/rop.lower, lop.lower*1/rop.upper),
			fmin(lop.upper*1/rop.lower, lop.upper*1/rop.upper));
		m.upper = fmax(fmax(lop.lower*1/rop.lower, lop.lower*1/rop.upper),
			fmax(lop.upper*1/rop.lower, lop.upper*1/rop.upper));
		return m;
	}
	friend ostream& operator<<(ostream &out, Interval<T> &rop)
	{
		out << "[" << rop.lower << "," << rop.upper << "]" << endl;
		return out;
	}
private:
	T lower;
	T upper;
};

